package com.bigknow.appstore.web.console.dao.impl;

import com.bigknow.appstore.common.util.StringUtils;
import com.bigknow.appstore.proxy.entity.ProxyLog;
import com.bigknow.appstore.web.base.entity.User;
import com.bigknow.appstore.web.console.app.Application;
import com.bigknow.appstore.web.console.dao.IProxyLogDao;
import com.bigknow.appstore.web.framework.dao.AbstractDao;
import com.bigknow.appstore.web.framework.util.AuthenticateUserUtil;
import com.bigknow.appstore.web.framework.vo.Page;
import org.mongodb.morphia.query.Query;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by chaos on 2016/10/19.
 */
@Component
public class ProxyLogDao extends AbstractDao<ProxyLog> implements IProxyLogDao {

    @Override
    public Page<ProxyLog> find(ProxyLog log, int pageIndex, int pageSize) {
        Query<ProxyLog> query = datastore.createQuery(ProxyLog.class);
        if (log != null) {
            for (Field field : log.getClass().getFields()) {
                try {
                    Object value = field.get(log);
                    if (value != null && StringUtils.isNotBlank(value.toString())) {
                        // All type process as string.
                        if (boolean.class.getSimpleName().equalsIgnoreCase(field.getType().getName())) {
                            query.filter(field.getName(), Boolean.valueOf(value.toString()));
                        } else {
                            query.field(field.getName()).equal(value.toString());
                        }
                    }
                } catch (IllegalAccessException e) {
                    this.logger.warn("Page find error.", e);
                }
            }
            addQueryForFind(log, query);
        }
        addAppIdsQuery(query);
        return toPage(log.getOrderBy(), query, pageIndex, pageSize);
    }

    public Page<ProxyLog> findWithFuzzy(ProxyLog log, int pageIndex, int pageSize) {
        Query<ProxyLog> query = datastore.createQuery(ProxyLog.class);
        if (log != null) {
            List<String> fuzzyFieldNames = new ArrayList<>();
            for (Field field : queryFields) {
                try {
                    Object value = field.get(log);
                    if (value != null && StringUtils.isNotBlank(value.toString())) {
                        // All type process as string.
                        query.filter(field.getName(), value);
//                        query.field(field.getName()).contains(value.toString());
                    } else if (StringUtils.isNotBlank(log.getFuzzyField())) {
                        fuzzyFieldNames.add(field.getName());
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            addCriteriaWithFuzzField(log, query, fuzzyFieldNames);
        }
        addAppIdsQuery(query);
        return toPage(log.getOrderBy(), query, pageIndex, pageSize);
    }

    private void addAppIdsQuery(Query<ProxyLog> query) {
        //加入特殊查询条件,只有resId是自己创建的应用日志才能访问
        if (!AuthenticateUserUtil.isCurrentUserIsSysAdmin()) {
            User user = AuthenticateUserUtil.getUser();
            List<String> list = getAppIdList(user);
            if (list.size() > 0) {
                query.filter("proxyResId in", list);
            } else {
                //不能直接传空的list
                list.add("null-value");
                query.filter("proxyResId in", list);
            }
        }
    }

    private List<String> getAppIdList(User user) {
        return datastore.find(Application.class).retrievedFields(true, "id")
                .field("userId").equal(user.getId()).asList().stream()
                .map(app -> app.getId()).collect(Collectors.toList());
    }
}
